Geometric Operations, array and matrix operations¶

Pillow¶

Created on JupyterLab

Objectives

Here, geometric transformations will be applied to an image. This allows to perform different operations like reshape translation, i.e. to shift, reshape and rotate the image. Then, some basic array and matrix operations will be applied to the image.

  • Geometric Operations
    • Scaling
    • Translation
    • Rotation
  • Mathematical Operations
    • Array Operations
    • Matix Operations n

In [1]:
# Libraries

import matplotlib.pyplot as plt
from PIL import Image
import numpy as np

First, let's define a helper function to plot two images side-by-side.

In [2]:
def plot_image(image_1, image_2,title_1="Orignal",title_2="New Image"):
    plt.figure(figsize=(10,10))
    plt.subplot(1, 2, 1)
    plt.imshow(image_1,cmap="gray")
    plt.title(title_1)
    plt.subplot(1, 2, 2)
    plt.imshow(image_2,cmap="gray")
    plt.title(title_2)
    plt.show()

Geometric Transformations¶

Geometric transformations allow you to perform different operations like translation, i.e. to shift, reshape and rotate the image.

We can resize an image using the method resize() of PIL images, which takes the resized image's width and height as paramters.

Consider the following image:

In [3]:
image = Image.open("lenna.png")
plt.imshow(image)
plt.show()

We can scale the horizontal axis by two and leave the vertical axis as is:

In [4]:
width, height = image.size
new_width = 2 * width
new_hight = height
new_image = image.resize((new_width, new_hight))
plt.imshow(new_image)
plt.show()

In the same manner, we can scale the vertical axis by two:

In [5]:
new_width = width
new_hight = 2 * height
new_image = image.resize((new_width, new_hight))
plt.imshow(new_image)
plt.show()

We can double both the width and the height of the image:

In [6]:
new_width = 2 * width
new_hight = 2 * height
new_image = image.resize((new_width, new_hight))
plt.imshow(new_image)
plt.show()

We can also shrink the image's width and height both by 1/2:

In [7]:
new_width = width // 2
new_hight = height // 2

new_image = image.resize((new_width, new_hight))
plt.imshow(new_image)
plt.show()

Rotation¶

We can rotate an image by angle $\theta$, using the method rotate.

We can rotate our toy image by 45 degrees:

In [8]:
theta = 45
new_image = image.rotate(theta)
In [9]:
plt.imshow(new_image)
plt.show()

Mathematical Operations¶

Array Operations¶

We can perform array operations on an image; Using Python broadcasting, we can add a constant to each pixel's intensity value.

Before doing that, we must first we convert the PIL image to a numpy array.

In [10]:
image = np.array(image)

We can then add the constant to the image array:

In [11]:
new_image = image + 20
plt.imshow(new_image)
plt.show()

We can also multiply every pixel's intensity value by a constant value.

In [12]:
new_image = 10 * image
plt.imshow(new_image)
plt.show()

We can add the elements of two arrays of equal shape. In this example, we generate an array of random noises with the same shape and data type as our image.

In [13]:
Noise = np.random.normal(0, 20, (height, width, 3)).astype(np.uint8)
Noise.shape
Out[13]:
(512, 512, 3)

We add the generated noise to the image and plot the result. We see the values that have corrupted the image:

In [14]:
new_image = image + Noise

plt.imshow(new_image)
plt.show()

At the same time, we can multiply the elements of two arrays of equal shape. We can multiply the random image and the Lenna image and plot the result.

In [15]:
new_image = image*Noise

plt.imshow(new_image)
plt.show()

Matrix Operations¶

Grayscale images are matrices. Consider the following grayscale image:

In [16]:
im_gray = Image.open("barbara.png")

Even though the image is gray, it has three channels; we can convert it to a one-channel image.

In [17]:
from PIL import ImageOps 
In [18]:
im_gray = ImageOps.grayscale(im_gray) 

We can convert the PIL image to a numpy array:

In [19]:
im_gray = np.array(im_gray )
In [20]:
plt.imshow(im_gray,cmap='gray')
plt.show()

We can apply algorithms designed for matrices. We can use Singular Value Decomposition, decomposing our image matrix into a product of three matrices.

In [21]:
U, s, V = np.linalg.svd(im_gray , full_matrices=True)

We see s is not rectangular:

In [22]:
s.shape
Out[22]:
(512,)

We can convert s to a diagonal matrix S:

In [23]:
S = np.zeros((im_gray.shape[0], im_gray.shape[1]))
S[:image.shape[0], :image.shape[0]] = np.diag(s)

We can plot the matrix U and V:

In [24]:
plot_image(U, V, title_1="Matrix U", title_2="Matrix V")

We see most of the elements in S are zero:

In [25]:
plt.imshow(S, cmap='gray')
plt.show()

We can find the matrix product of all the matrices. First, we can perform matrix multiplication on S and U and assign it to B and plot the results:

In [26]:
B = S.dot(V)
plt.imshow(B,cmap='gray')
plt.show()

We can find the matrix product of U, S, and B. We see it's the entire image:

In [27]:
A = U.dot(B)
In [28]:
plt.imshow(A,cmap='gray')
plt.show()

It turns out that many elements are redundant. We can eliminate some rows and columns of S and V and approximate the image by finding the product:

In [29]:
for n_component in [1,10,100,200, 500]:
    S_new = S[:, :n_component]
    V_new = V[:n_component, :]
    A = U.dot(S_new.dot(V_new))
    plt.imshow(A,cmap='gray')
    plt.title("Number of Components:"+str(n_component))
    plt.show()

We see we only need 100 to 200 Components to represent the image.

Authors' rights¶

Machine Learning with Python course by IBM on Coursera: https://www.coursera.org/learn/machine-learning-with-python/

Completed and modified by Mathilde Marie Duville as part of the IBM Artificial Intelligence Engineering Professional Certificate and corresponding IBM badges. Please, follow the subsequent links to confirm the accreditation:

https://www.coursera.org/account/accomplishments/professional-cert/KSLW773DAATP?utm_source=link&utm_medium=certificate&utm_content=cert_image&utm_campaign=sharing_cta&utm_product=prof

https://www.credly.com/users/mathilde-marie-duville/badges


Authors: Joseph Santarcangelo has a PhD in Electrical Engineering, his research focused on using machine learning, signal processing, and computer vision to determine how videos impact human cognition. Joseph has been working for IBM since he completed his PhD.

References¶

[1] Images were taken from: https://homepages.cae.wisc.edu/~ece533/images/

[2] Pillow Docs

[3] Open CV

[4] Gonzalez, Rafael C., and Richard E. Woods. "Digital image processing." (2017).

[5 ] Jian, Wushuai, Xueyan Sun, and Shuqian Luo. "Computer-aided diagnosis of breast microcalcifications based on dual-tree complex wavelet transform." Biomedical engineering online 11.1 (2012): 1-12.

© IBM Corporation. All rights reserved.